﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApMovAviGeneratorApp
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EMPAPPLICATIONLib;
using EMPTYPELIBRARYLib;
using System;
using System.Collections;
using System.Globalization;
using System.IO;
using System.Resources;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.PrivateImplementationDetails;
using Tecnomatix.Planning;


namespace DnProcessSimulateCommands;

public class CApMovAviGeneratorApp
{
  private int m_objectsCountWithMovies;
  private bool m_shouldContinue = true;
  private string m_newFileName;
  private CApMovMovieRecorder m_recorder;
  private ITxOperation m_rootOperation;
  private ITxPlanningObject m_currentOperation;
  private TxSimulationPlayer m_simulationPlayer;
  private bool m_isWaitingTorecording;
  private string[] m_systemChirecters;
  private TxTypeFilter m_operationFilter;
  private Hashtable m_operationNodeDataAndOperationRecordered;
  private string m_additionalFailureInformation;
  private Hashtable m_rootOperationsAndDescendants;
  private bool m_changeCurrentOperation;

  public event CApMovAviGeneratorApp.CApMovAviGenerator_AVIAttachmentCreatedEventHandler AVIAttachmentCreated;

  public event CApMovAviGeneratorApp.CApMovAviGenerator_SimulationStopedOnUserRequestEventHandler SimulationStopedOnUserRequest;

  public int CreatedMoviesCount => this.m_objectsCountWithMovies;

  public CApMovAviGeneratorApp(CApMovMovieRecorder recorder)
  {
    this.m_objectsCountWithMovies = 0;
    this.m_additionalFailureInformation = "";
    this.m_simulationPlayer = TxApplication.ActiveDocument.SimulationPlayer;
    this.m_simulationPlayer.DoOnlyUnscheduledReset(false);
    this.m_simulationPlayer.AskUserForReset(false);
    this.m_operationNodeDataAndOperationRecordered = new Hashtable();
    this.m_rootOperationsAndDescendants = new Hashtable();
    this.m_isWaitingTorecording = false;
    this.m_recorder = recorder;
    this.InitializeSystemChiractersArray();
    this.m_operationFilter = new TxTypeFilter(new Type[1]
    {
      typeof (ITxCompoundOperation)
    }, new Type[1]{ typeof (ITxLocationOperation) });
  }

  public bool StartGenerationProcess(
    CApMovMovieManagerApp.AVIGenerationMode generationMode,
    ArrayList selectedObjects)
  {
    bool flag = true;
    string noPerminissionsMessage;
    if (this.HaveWritePermissionsToDesitnationFolder(out noPerminissionsMessage))
    {
      foreach (CApMovMovieManagerNodeData selectedObject in selectedObjects)
      {
        if (this.ShouldCreateMovie(generationMode, selectedObject))
          this.m_operationNodeDataAndOperationRecordered.Add((object) selectedObject.NodeObject, (object) false);
      }
      foreach (DictionaryEntry dictionaryEntry in this.m_operationNodeDataAndOperationRecordered)
      {
        ITxOperation currentRootOperation = this.GetCurrentRootOperation(((ITxPlanningObject) dictionaryEntry.Key).EngineeringRepresentation as ITxOperation, selectedObjects);
        if (!this.m_rootOperationsAndDescendants.Contains((object) currentRootOperation))
          this.m_rootOperationsAndDescendants.Add((object) currentRootOperation, (object) new ArrayList()
          {
            dictionaryEntry.Key
          });
        else
          (this.m_rootOperationsAndDescendants[(object) currentRootOperation] as ArrayList).Add(dictionaryEntry.Key);
      }
      foreach (DictionaryEntry operationsAndDescendant in this.m_rootOperationsAndDescendants)
      {
        this.m_rootOperation = operationsAndDescendant.Key as ITxOperation;
        TxApplication.ActiveDocument.CurrentOperation = (ITxOperation) null;
        TxApplication.ActiveDocument.CurrentOperation = this.m_rootOperation;
        this.m_simulationPlayer.Rewind();
        if (this.IsNotRecorderedOperations())
          flag &= this.StartMovieGenerationForAllRoots(generationMode, selectedObjects);
      }
    }
    else
      this.m_additionalFailureInformation = noPerminissionsMessage;
    return flag;
  }

  public int GetSelectedObjectCountToGenerateMovies(
    CApMovMovieManagerApp.AVIGenerationMode generationMode,
    ArrayList allObjects)
  {
    int toGenerateMovies = 0;
    foreach (CApMovMovieManagerNodeData allObject in allObjects)
    {
      if (this.ShouldCreateMovie(generationMode, allObject))
        ++toGenerateMovies;
    }
    return toGenerateMovies;
  }

  public void StopGenerationProcess() => this.m_shouldContinue = false;

  public void ShowDetailedMessage(int notCreatedMoviesCount)
  {
    ResourceManager resourceManager = this.GetResourceManager();
    string str1 = resourceManager.GetString("AVI_GENERATOR_PROGRESSBAR_COMMAND_TITLE");
    string str2;
    if (notCreatedMoviesCount > 0)
    {
      str2 = string.Format(resourceManager.GetString("MOVIE_MANAGER_FINAL_MESSAGE_FAILURE"), (object) notCreatedMoviesCount.ToString());
      if (this.m_additionalFailureInformation != "")
        str2 = $"{str2} {this.m_additionalFailureInformation}";
    }
    else
      str2 = resourceManager.GetString("MOVIE_MANAGER_FINAL_MESSAGE_SUCCESSFULL");
    int num = (int) TxMessageBox.Show(str2, str1, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
  }

  internal void CleanTemporaryChanges()
  {
    this.m_simulationPlayer.AskUserForReset(true);
    this.m_simulationPlayer.DoOnlyUnscheduledReset(false);
  }

  private ResourceManager GetResourceManager()
  {
    return new ResourceManager("DnProcessSimulateCommands.StringTable", this.GetType().Assembly);
  }

  private bool ShouldCreateMovie(
    CApMovMovieManagerApp.AVIGenerationMode generationMode,
    CApMovMovieManagerNodeData nodeData)
  {
    bool movie = false;
    if (nodeData.IsNodeOperationSelected)
    {
      if (CApMovMovieManagerApp.AVIGenerationMode.CreateMissingMovies == generationMode && !nodeData.IsNodeHasAVIAttachments)
        movie = true;
      else if (CApMovMovieManagerApp.AVIGenerationMode.CreateMissingMovies != generationMode)
        movie = true;
    }
    return movie;
  }

  private bool StartMovieGenerationForAllRoots(
    CApMovMovieManagerApp.AVIGenerationMode generationMode,
    ArrayList selectedObjects)
  {
    bool flag = false;
    while (this.IsNotRecorderedOperations() && this.m_shouldContinue && !this.IsAllDescendatnsRecordered())
    {
      string generatedAVIAsFileAttachment = this.StratRecorderRootOperation();
      if (this.m_shouldContinue)
      {
        CApMovMovieManagerNodeData recorderedNodeData = this.GetCurrentRecorderedNodeData(selectedObjects);
        if (generatedAVIAsFileAttachment != "")
        {
          if (CApMovMovieManagerApp.AVIGenerationMode.OverrideAllMovies == generationMode)
            recorderedNodeData.RemoveAllAttachments();
          flag = this.AttachCreatedFile(recorderedNodeData);
        }
        else
        {
          this.m_operationNodeDataAndOperationRecordered[(object) this.m_currentOperation] = (object) true;
          flag = false;
          this.StopSimulationOnError();
        }
        if (this.AVIAttachmentCreated != null)
          this.AVIAttachmentCreated((object) this, new CApMovAviGeneratorApp.CApMovAviGenerator_AVICreatedEventArgs(recorderedNodeData.NodeObject.EngineeringRepresentation as ITxOperation, generatedAVIAsFileAttachment));
      }
      else
      {
        flag = false;
        this.StopSimulationOnError();
        break;
      }
    }
    return flag;
  }

  private bool IsAllDescendatnsRecordered()
  {
    return !(this.m_rootOperationsAndDescendants[(object) this.m_rootOperation] is ArrayList operationsAndDescendant) || operationsAndDescendant.Count <= 0;
  }

  private CApMovMovieManagerNodeData GetCurrentRecorderedNodeData(ArrayList selectedObjects)
  {
    CApMovMovieManagerNodeData recorderedNodeData = (CApMovMovieManagerNodeData) null;
    foreach (CApMovMovieManagerNodeData selectedObject in selectedObjects)
    {
      if (selectedObject.NodeObject == this.m_currentOperation)
      {
        recorderedNodeData = selectedObject;
        break;
      }
    }
    return recorderedNodeData;
  }

  private ITxOperation GetCurrentRootOperation(ITxOperation currentOp, ArrayList allLoadedObjects)
  {
    bool flag = false;
    ITxOperation currentOp1 = currentOp;
    while (!flag && currentOp1 != this.m_rootOperation)
    {
      ITxObject parrentOperation = this.GetParrentOperation(currentOp1);
      if (parrentOperation == TxApplication.ActiveDocument.OperationRoot || !this.IsOperationLoded(allLoadedObjects, parrentOperation as ITxOperation))
        flag = true;
      else
        currentOp1 = parrentOperation as ITxOperation;
    }
    return currentOp1;
  }

  private bool IsOperationLoded(ArrayList allLoadedObjects, ITxOperation currentObj)
  {
    bool flag = false;
    foreach (CApMovMovieManagerNodeData allLoadedObject in allLoadedObjects)
    {
      if (allLoadedObject.NodeObject.EngineeringRepresentation == currentObj)
      {
        flag = true;
        break;
      }
    }
    return flag;
  }

  private ITxObject GetParrentOperation(ITxOperation currentOp)
  {
    return (ITxObject) ((ITxObject) currentOp).Collection;
  }

  private bool AttachCreatedFile(CApMovMovieManagerNodeData objData)
  {
    bool flag = false;
    try
    {
      if (objData != null)
      {
        objData.AddAttachment(this.m_newFileName);
        ++this.m_objectsCountWithMovies;
        flag = true;
      }
    }
    catch
    {
      flag = false;
    }
    return flag;
  }

  private bool IsNotRecorderedOperations()
  {
    bool flag = false;
    foreach (DictionaryEntry dictionaryEntry in this.m_operationNodeDataAndOperationRecordered)
    {
      if (!(bool) dictionaryEntry.Value)
      {
        flag = !(bool) dictionaryEntry.Value;
        break;
      }
    }
    return flag;
  }

  private bool ShouldRecorderOperation(ITxPlanningObject currentOperation)
  {
    bool flag = false;
    if (currentOperation != null && this.m_operationNodeDataAndOperationRecordered.Contains((object) currentOperation))
      flag = !(bool) this.m_operationNodeDataAndOperationRecordered[(object) currentOperation];
    return flag;
  }

  private void StopSimulationOnError()
  {
    Cursor.Current = Cursors.WaitCursor;
    this.UnRegisterFromSimulationEvents();
    if (this.m_simulationPlayer.IsSimulationRunning())
    {
      this.m_simulationPlayer.Stop();
      if (this.SimulationStopedOnUserRequest != null && !this.m_shouldContinue)
        this.SimulationStopedOnUserRequest((object) this, new EventArgs());
    }
    if (this.m_recorder != null && this.m_recorder.IsActive)
      this.m_recorder.StopRecording();
    this.m_simulationPlayer.Rewind();
  }

  private string StratRecorderRootOperation()
  {
    try
    {
      this.m_simulationPlayer.DoOnlyUnscheduledReset(false);
      TxApplication.ActiveDocument.CurrentOperation = this.m_rootOperation;
      this.RegisterToSimulationEvents();
      this.m_isWaitingTorecording = true;
      this.m_simulationPlayer.Play();
      this.UnRegisterFromSimulationEvents();
      if (this.m_isWaitingTorecording)
      {
        this.m_newFileName = "";
        if (this.m_recorder.IsActive)
        {
          this.m_recorder.StopRecording();
          this.m_simulationPlayer.Stop();
        }
      }
    }
    catch
    {
      this.StopSimulationOnError();
      this.m_newFileName = "";
    }
    finally
    {
      if (this.m_currentOperation != null)
        this.m_operationNodeDataAndOperationRecordered[(object) this.m_currentOperation] = (object) true;
      this.m_simulationPlayer.Rewind();
    }
    return this.m_newFileName;
  }

  private void InitializeSystemChiractersArray()
  {
    this.m_systemChirecters = new string[9];
    this.m_systemChirecters[0] = "\\";
    this.m_systemChirecters[1] = "/";
    this.m_systemChirecters[2] = ":";
    this.m_systemChirecters[3] = "*";
    this.m_systemChirecters[4] = "?";
    this.m_systemChirecters[5] = "\"";
    this.m_systemChirecters[6] = "<";
    this.m_systemChirecters[7] = ">";
    this.m_systemChirecters[8] = "|";
  }

  private string GetFileName(string fileName, ITxPlanningObject selectedObject)
  {
    int startIndex = 32 /*0x20*/;
    if (TxApplication.PlatformType == 1)
      startIndex = 251;
    string fileName1 = fileName;
    if (fileName1.Length > startIndex + 4)
      fileName1 = fileName1.Remove(startIndex, fileName1.Length - startIndex - 4);
    return this.GetUniqueFileNameExtansion(this.AddSpecificPathToFileName(fileName1, selectedObject));
  }

  private string RemoveSystemChiracters(string fileName)
  {
    int index = 0;
    for (int length = this.m_systemChirecters.Length; index < length; ++index)
      fileName = fileName.Replace(this.m_systemChirecters[index], "");
    return fileName;
  }

  private string GetDataTimeExtansion()
  {
    return DateTime.Now.ToString("ddMMyyyy'_'HHmm", (IFormatProvider) DateTimeFormatInfo.InvariantInfo);
  }

  private string AddSpecificPathToFileName(string fileName, ITxPlanningObject selectedObject)
  {
    string fileName1 = "";
    try
    {
      if (TxApplication.PlatformType == 1)
      {
        string attachmentsDirectory = TxApplication.Options.EMServer.MovieAttachmentsDirectory;
        if (attachmentsDirectory == "")
          fileName1 = $"{TxApplication.SystemRootDirectory}\\Images\\{this.GetNodeExternalId(selectedObject)}\\{this.GetVersionId()}";
        else
          fileName1 = $"{attachmentsDirectory}\\{this.GetNodeExternalId(selectedObject)}\\{this.GetVersionId()}";
        if (!Directory.Exists(fileName1))
          Directory.CreateDirectory(fileName1);
        fileName1 = this.IsCreatedDirectoryReadOnly(fileName1) ? "" : $"{fileName1}\\{fileName}";
      }
      else if (TxTcUtilities.IsTcAnyPlatform)
        fileName1 = Path.GetTempPath() + fileName;
    }
    catch
    {
      fileName1 = "";
    }
    finally
    {
      if (fileName1 == "")
      {
        this.m_additionalFailureInformation = this.GetResourceManager().GetString("MOVIE_MANAGER_FINAL_ACSESS_MESSAGE_FAILURE");
        this.m_operationNodeDataAndOperationRecordered[(object) this.m_currentOperation] = (object) true;
      }
    }
    return fileName1;
  }

  private string GetUniqueFileNameExtansion(string fileName)
  {
    int num = 1;
    while (File.Exists(fileName))
    {
      string str = "_" + num.ToString();
      int startIndex = fileName.Length - str.Length - 4;
      fileName = fileName.Remove(startIndex, str.Length);
      fileName = fileName.Insert(startIndex, str);
      ++num;
    }
    return fileName;
  }

  private string GetNodeExternalId(ITxPlanningObject selectedObject)
  {
    string nodeExternalId = selectedObject.ProcessModelId.ExternalId;
    int index = 0;
    for (int length = this.m_systemChirecters.Length; index < length; ++index)
      nodeExternalId = nodeExternalId.Replace(this.m_systemChirecters[index], "_");
    return nodeExternalId;
  }

  private string GetVersionId()
  {
    EmpVersionKey empVersionKey1;
    EmpVersionKey empVersionKey2;
    ((IEmpApplication) new EmpApplicationClass()).GetCurrentConfigSpec(ref empVersionKey1, ref empVersionKey2);
    return "version_" + empVersionKey2.versionId.ToString();
  }

  private bool IsCreatedDirectoryReadOnly(string directoryName)
  {
    bool flag = false;
    try
    {
      DirectoryInfo directoryInfo = new DirectoryInfo(directoryName);
      string str = directoryName + "\\tmpDir";
      directoryInfo.CreateSubdirectory("tmpDir").Delete(true);
    }
    catch (UnauthorizedAccessException ex)
    {
      flag = true;
    }
    return flag;
  }

  private bool HaveWritePermissionsToDesitnationFolder(out string noPerminissionsMessage)
  {
    bool desitnationFolder = false;
    noPerminissionsMessage = string.Empty;
    if (TxApplication.PlatformType == 1)
    {
      string str = TxApplication.Options.EMServer.MovieAttachmentsDirectory;
      if (string.IsNullOrEmpty(str))
        str = TxApplication.SystemRootDirectory + "\\Images\\";
      if (!Directory.Exists(str))
      {
        try
        {
          Directory.CreateDirectory(str);
        }
        catch (UnauthorizedAccessException ex)
        {
          noPerminissionsMessage = string.Format(StringTable.MOVIE_MANAGER_SYSTEMROOT_IMAGES_SECURITY_WARNNING, (object) str);
          return desitnationFolder;
        }
      }
      desitnationFolder = !this.IsCreatedDirectoryReadOnly(str);
      if (!desitnationFolder)
        noPerminissionsMessage = string.Format(StringTable.MOVIE_MANAGER_SYSTEMROOT_SECURITY_WARNNING, (object) str);
    }
    else if (TxTcUtilities.IsTcAnyPlatform)
      desitnationFolder = true;
    return desitnationFolder;
  }

  private void GenerateFileNameByOperation(ITxPlanningObject currentOperation)
  {
    this.m_newFileName = $"{this.RemoveSystemChiracters(((ITxObject) currentOperation).Name)}_{this.GetDataTimeExtansion()}{this.m_recorder.MovieFileExtension}";
    this.m_newFileName = this.GetFileName(this.m_newFileName, currentOperation);
  }

  private ITxPlanningObject GetObjectPlanningRepresentation(ITxObject obj)
  {
    ITxProcessModelObject processModelObject = obj as ITxProcessModelObject;
    if (!(obj is ITxPlanningObject planningRepresentation) && processModelObject != null)
      planningRepresentation = processModelObject.PlanningRepresentation;
    return planningRepresentation;
  }

  private void RegisterToSimulationEvents()
  {
    this.m_simulationPlayer.OperationStartedForward += new TxSimulationPlayer_OperationStartedForwardEventHandler(this.OperationStartedForward);
    this.m_simulationPlayer.OperationEndedForward += new TxSimulationPlayer_OperationEndedForwardEventHandler(this.OperationEndedForward);
    this.m_simulationPlayer.SimulationEndedForward += new TxSimulationPlayer_SimulationEndedForwardEventHandler(this.SimulationEndedForward);
    this.m_simulationPlayer.SimulationStopped += new TxSimulationPlayer_SimulationStoppedEventHandler(this.SimulationStopped);
  }

  private void UnRegisterFromSimulationEvents()
  {
    this.m_simulationPlayer.OperationStartedForward -= new TxSimulationPlayer_OperationStartedForwardEventHandler(this.OperationStartedForward);
    this.m_simulationPlayer.OperationEndedForward -= new TxSimulationPlayer_OperationEndedForwardEventHandler(this.OperationEndedForward);
    this.m_simulationPlayer.SimulationEndedForward -= new TxSimulationPlayer_SimulationEndedForwardEventHandler(this.SimulationEndedForward);
    this.m_simulationPlayer.SimulationStopped -= new TxSimulationPlayer_SimulationStoppedEventHandler(this.SimulationStopped);
  }

  public void OperationStartedForward(
    object sender,
    TxSimulationPlayer_OperationStartedForwardEventArgs args)
  {
    ITxPlanningObject planningRepresentation = this.GetObjectPlanningRepresentation((ITxObject) args.Operation);
    if (!this.ShouldRecorderOperation(planningRepresentation) || this.m_changeCurrentOperation || this.m_recorder.IsActive || this.m_currentOperation == planningRepresentation || !(this.m_rootOperationsAndDescendants[(object) this.m_rootOperation] is ArrayList operationsAndDescendant) || !operationsAndDescendant.Contains((object) planningRepresentation))
      return;
    this.m_currentOperation = planningRepresentation;
    operationsAndDescendant.Remove((object) planningRepresentation);
    this.GenerateFileNameByOperation(this.m_currentOperation);
    if (!this.m_isWaitingTorecording || this.m_currentOperation == null || !(this.m_newFileName != "") || this.m_currentOperation == this.m_rootOperation)
      return;
    this.m_changeCurrentOperation = true;
    this.m_simulationPlayer.Stop();
  }

  private void OperationEndedForward(
    object sender,
    TxSimulationPlayer_OperationEndedForwardEventArgs args)
  {
  }

  private void SimulationEndedForward(
    object sender,
    TxSimulationPlayer_SimulationEndedForwardEventArgs args)
  {
    if (!this.m_recorder.IsActive)
      return;
    this.m_isWaitingTorecording = false;
    this.m_recorder.StopRecording();
  }

  private void SimulationStopped(object sender, TxSimulationPlayer_SimulationStoppedEventArgs args)
  {
    if (!this.m_changeCurrentOperation)
      return;
    this.m_changeCurrentOperation = false;
    this.UnRegisterFromSimulationEvents();
    this.m_simulationPlayer.DoOnlyUnscheduledReset(true);
    TxApplication.ActiveDocument.CurrentOperation = this.m_currentOperation.EngineeringRepresentation as ITxOperation;
    this.RegisterToSimulationEvents();
    this.m_recorder.StartRecording(this.m_newFileName);
    this.m_simulationPlayer.Play();
  }

  public delegate void CApMovAviGenerator_AVIAttachmentCreatedEventHandler(
    object sender,
    CApMovAviGeneratorApp.CApMovAviGenerator_AVICreatedEventArgs args);

  public class CApMovAviGenerator_AVICreatedEventArgs : EventArgs
  {
    private ITxOperation m_parentOperation;
    private string m_generatedAVIAsFileAttachment;

    public CApMovAviGenerator_AVICreatedEventArgs(
      ITxOperation parentObject,
      string generatedAVIAsFileAttachment)
    {
      this.m_parentOperation = parentObject;
      this.m_generatedAVIAsFileAttachment = generatedAVIAsFileAttachment;
    }

    public ITxOperation ParentOperation => this.m_parentOperation;

    public object GeneratedAVIAsFileAttachment => (object) this.m_generatedAVIAsFileAttachment;
  }

  public delegate void CApMovAviGenerator_SimulationStopedOnUserRequestEventHandler(
    object sender,
    EventArgs args);
}
